#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
阿里AI聊天插件
"""

import json
import os
import aiohttp
from datetime import datetime
from typing import Dict, Optional, Any, List
from common.logger import logger
from plugins.base_plugin import BasePlugin
from plugins.event_system import Event, EventType, on_message, on_any_message, middleware


class AliAIPlugin(BasePlugin):
    """阿里AI聊天插件类"""
    
    def __init__(self, config: Dict[str, Any], event_bus):
        super().__init__(config, event_bus)
        self.api_url = self.settings.get("api_url", "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation")
        self.api_key = self.settings.get("api_key", "")
        self.model = self.settings.get("model", "qwen-turbo")
        self.keywords = self.settings.get("keywords", ["阿里", "ali", "ai", "智能", "聊天"])
        self.max_context_length = self.settings.get("max_context_length", 10)
        self.temperature = self.settings.get("temperature", 0.7)
        self.max_tokens = self.settings.get("max_tokens", 1500)
        self.context_file = self.settings.get("context_storage", "data/ali_context.json")
        
        # 确保数据目录存在
        os.makedirs("data", exist_ok=True)
        
        # 加载上下文数据
        self.context_data = self._load_context()
    
    def _load_context(self) -> Dict[str, Any]:
        """加载上下文数据"""
        try:
            if os.path.exists(self.context_file):
                with open(self.context_file, "r", encoding="utf-8") as f:
                    return json.load(f)
        except Exception as e:
            logger.error(f"加载上下文数据失败: {e}")
        return {}
    
    def _save_context(self):
        """保存上下文数据"""
        try:
            with open(self.context_file, "w", encoding="utf-8") as f:
                json.dump(self.context_data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            logger.error(f"保存上下文数据失败: {e}")
    
    def _get_user_context(self, user_id: str) -> List[Dict[str, Any]]:
        """获取用户上下文"""
        if user_id not in self.context_data:
            self.context_data[user_id] = []
        return self.context_data[user_id]
    
    def _add_to_context(self, user_id: str, role: str, content: str):
        """添加上下文"""
        context = self._get_user_context(user_id)
        context.append({
            "role": role,
            "content": content,
            "timestamp": datetime.now().isoformat()
        })
        
        # 限制上下文长度
        if len(context) > self.max_context_length * 2:
            context = context[-self.max_context_length * 2:]
            self.context_data[user_id] = context
        
        self._save_context()
    
    def _clear_context(self, user_id: str):
        """清除用户上下文"""
        if user_id in self.context_data:
            del self.context_data[user_id]
            self._save_context()
    
    def _check_keywords(self, content: str) -> bool:
        """检查是否包含关键词"""
        content_lower = content.lower()
        return any(keyword.lower() in content_lower for keyword in self.keywords)
    
    async def _call_ali_api(self, user_id: str, message: str) -> Optional[str]:
        """调用阿里AI API"""
        try:
            if not self.api_key:
                return "❌ 阿里AI API密钥未配置，请联系管理员"
            
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json"
            }
            
            # 获取用户上下文
            context = self._get_user_context(user_id)
            
            # 构建消息列表
            messages = []
            
            # 添加历史上下文
            if context:
                for ctx in context[-self.max_context_length * 2:]:
                    messages.append({
                        "role": ctx["role"],
                        "content": ctx["content"]
                    })
            
            # 添加当前消息
            messages.append({
                "role": "user",
                "content": message
            })
            
            # 构建请求数据
            data = {
                "model": self.model,
                "input": {
                    "messages": messages
                },
                "parameters": {
                    "temperature": self.temperature,
                    "max_tokens": self.max_tokens,
                    "top_p": 0.8,
                    "result_format": "message"
                }
            }
            
            async with aiohttp.ClientSession() as session:
                async with session.post(self.api_url, headers=headers, json=data) as response:
                    if response.status == 200:
                        result = await response.json()
                        
                        # 解析阿里AI返回格式
                        if result.get("code") == 200:
                            output = result.get("output", {})
                            choices = output.get("choices", [])
                            
                            if choices:
                                answer = choices[0].get("message", {}).get("content", "")
                                
                                # 保存到上下文
                                self._add_to_context(user_id, "user", message)
                                self._add_to_context(user_id, "assistant", answer)
                                
                                return answer
                            else:
                                return "❌ AI返回内容为空"
                        else:
                            error_msg = result.get("message", "未知错误")
                            logger.error(f"阿里AI API返回错误: {error_msg}")
                            return f"❌ AI服务返回错误: {error_msg}"
                    else:
                        error_text = await response.text()
                        logger.error(f"阿里AI API调用失败: {response.status} - {error_text}")
                        return f"❌ AI服务暂时不可用，请稍后重试"
                        
        except Exception as e:
            logger.error(f"调用阿里AI API失败: {e}")
            return f"❌ AI服务调用失败: {str(e)}"
    
    @on_message(EventType.MESSAGE_TEXT)
    async def handle_text_message(self, event: Event) -> Optional[Dict[str, Any]]:
        """处理文本消息事件"""
        try:
            if not self.is_enabled():
                return None
            
            data = event.data
            content = data.get("content", "")
            sender_wxid = data.get("sender_wxid", "")
            
            # 检查是否包含关键词
            if not self._check_keywords(content):
                return None
            
            # 处理特殊命令
            if content.lower() in ["清除上下文", "clear context", "重置对话"]:
                self._clear_context(sender_wxid)
                return self.create_text_response("✅ 对话上下文已清除")
            
            # 调用阿里AI API
            logger.info(f"阿里AI处理消息: {sender_wxid} -> {content}")
            response = await self._call_ali_api(sender_wxid, content)
            
            if response:
                return self.create_text_response(response)
            
            return None
            
        except Exception as e:
            logger.error(f"阿里AI插件处理消息失败: {e}")
            return self.create_text_response("❌ 处理消息时发生错误")
    
    async def on_unload(self):
        """插件卸载时保存上下文"""
        try:
            self._save_context()
            logger.info("阿里AI插件卸载，上下文已保存")
        except Exception as e:
            logger.error(f"保存上下文失败: {e}")


# 插件类名必须是Plugin
Plugin = AliAIPlugin 